package cn.lg.soar.common.util;

import cn.lg.soar.common.util.reflect.ReflectUtil;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;

/**
 * 主要用于数据库插入数据前做初始化操作
 * @author luguoxiang 469599794@qq.com
 * @Date: 2024/12/18 11:23
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
public abstract class InitializationUtils {

    /**
     * 设置初始值
     * @param data
     * @param mapper
     */
    public static void setInitValue(Object data, Map<Class<?>, Object> mapper) {
        ReflectUtil.scanField(data.getClass(), field -> {
            if (ReflectUtil.get(data, field) != null) {
                return;
            }
            Class<?> type = field.getType();
            if (mapper.containsKey(type)) {
                Object value = mapper.get(type);
                ReflectUtil.set(data, field, value);
                return;
            }
            if (BigDecimal.class.isAssignableFrom(type)) {
                ReflectUtil.set(data, field, BigDecimal.ZERO);
                return;
            }
            if (BigInteger.class.isAssignableFrom(type)) {
                ReflectUtil.set(data, field, BigInteger.ZERO);
                return;
            }
            if (Float.class.isAssignableFrom(type)) {
                ReflectUtil.set(data, field, 0F);
                return;
            }
            if (Double.class.isAssignableFrom(type)) {
                ReflectUtil.set(data, field, 0D);
                return;
            }
            if (Long.class.isAssignableFrom(type)) {
                ReflectUtil.set(data, field, 0L);
                return;
            }
            if (Number.class.isAssignableFrom(type)) {
                ReflectUtil.set(data, field, 0);
                return;
            }
            if (CharSequence.class.isAssignableFrom(type)) {
                ReflectUtil.set(data, field, "");
                return;
            }
            if (Boolean.class.isAssignableFrom(type)) {
                ReflectUtil.set(data, field, false);
                return;
            }
            if (Character.class.isAssignableFrom(type)) {
                ReflectUtil.set(data, field, "");
            }
            if (LocalDateTime.class.isAssignableFrom(type)) {
                ReflectUtil.set(data, field, LocalDateTime.now());
            }
            if (LocalDate.class.isAssignableFrom(type)) {
                ReflectUtil.set(data, field, LocalDate.now());
            }
            if (LocalTime.class.isAssignableFrom(type)) {
                ReflectUtil.set(data, field, LocalTime.MIN);
            }
            if (Date.class.isAssignableFrom(type)) {
                ReflectUtil.set(data, field, new Date());
            }
            if (List.class.isAssignableFrom(type)) {
                ReflectUtil.set(data, field, Collections.emptyList());
            }
            if (Set.class.isAssignableFrom(type)) {
                ReflectUtil.set(data, field, Collections.emptySet());
            }
            if (Map.class.isAssignableFrom(type)) {
                ReflectUtil.set(data, field, Collections.emptyMap());
            }
        });
    }

    /**
     * 设置初始值
     * @param data
     */
    public static void setInitValue(Object data) {
        setInitValue(data, MAPPER);
    }

    private final static Map<Class<?>, Object> MAPPER = new HashMap<>();

    static {
        MAPPER.put(Byte.class, 0);
        MAPPER.put(Short.class, 0);
        MAPPER.put(Integer.class, 0);
        MAPPER.put(Long.class, 0L);
        MAPPER.put(Float.class, 0F);
        MAPPER.put(Double.class, 0D);
        MAPPER.put(BigInteger.class, BigInteger.ZERO);
        MAPPER.put(BigDecimal.class, BigDecimal.ZERO);
        MAPPER.put(String.class, "");
        MAPPER.put(Character.class, "");
        MAPPER.put(Boolean.class, Boolean.FALSE);
        MAPPER.put(LocalDateTime.class, LocalDateTime.now());
        MAPPER.put(LocalDate.class, LocalDate.now());
        MAPPER.put(LocalTime.class, LocalTime.MIN);
        MAPPER.put(Date.class, new Date());
    }
}
